1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module glib.Timeout;
26 
27 private import core.time;
28 private import glib.Source;
29 private import glib.c.functions;
30 public  import glib.c.types;
31 private import std.conv;
32 
33 
34 /** */
35 public class Timeout
36 {
37 	/** Holds all idle delegates */
38 	private bool delegate()[] timeoutListeners;
39 	/** Our timeout ID */
40 	private uint timeoutID;
41 
42 
43 	/**
44 	 * Creates a new timeout cycle with the default priority, GPriority.DEFAULT.
45 	 *
46 	 * Note that timeout functions may be delayed, due to the processing of other
47 	 * event sources. Thus they should not be relied on for precise timing.
48 	 * After each call to the timeout function, the time of the next timeout is
49 	 * recalculated based on the current time and the given interval
50 	 * (it does not try to 'catch up' time lost in delays).
51 	 * Params:
52 	 *    	interval = 	the timeout in milieconds
53 	 *    	delegate() = 	the delegate to be executed
54 	 *    	fireNow = 	When true the delegate will be executed emmidiatly
55 	 */
56 	this(uint interval, bool delegate() dlg, bool fireNow=false)
57 	{
58 		if ( fireNow && !dlg() )
59 			return;
60 
61 		timeoutListeners ~= dlg;
62 		timeoutID = g_timeout_add_full(GPriority.DEFAULT, interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify);
63 	}
64 
65 	this(Duration interval, bool delegate() dlg, bool fireNow=false)
66 	{
67 		this(interval.total!"msecs".to!uint, dlg, fireNow);
68 	}
69 
70 	/**
71 	 * Creates a new timeout cycle.
72 	 * Params:
73 	 *    	interval = 	the timeout in milieconds
74 	 *    	delegate() = 	the delegate to be executed
75 	 *      priority = Priority for the timeout function
76 	 *    	fireNow = 	When true the delegate will be executed emmidiatly
77 	 */
78 	this(uint interval, bool delegate() dlg, GPriority priority, bool fireNow=false)
79 	{
80 		if ( fireNow && !dlg() )
81 			return;
82 
83 		timeoutListeners ~= dlg;
84 		timeoutID = g_timeout_add_full(priority, interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify);
85 	}
86 
87 	this(Duration interval, bool delegate() dlg, GPriority priority, bool fireNow=false)
88 	{
89 		this(interval.total!"msecs".to!uint, dlg, priority, fireNow);
90 	}
91 
92 	/**
93 	 * Creates a new timeout cycle with the default priority, GPriority.DEFAULT.
94 	 * Params:
95 	 *    	delegate() = 	the delegate to be executed
96 	 *      seconds = interval in seconds.
97 	 *    	fireNow = 	When true the delegate will be executed emmidiatly
98 	 */
99 	this(bool delegate() dlg, uint seconds, bool fireNow=false)
100 	{
101 		if ( fireNow && !dlg() )
102 			return;
103 
104 		timeoutListeners ~= dlg;
105 		timeoutID = g_timeout_add_seconds_full(GPriority.DEFAULT, seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify);
106 	}
107 
108 	this(bool delegate() dlg, Duration seconds, bool fireNow=false)
109 	{
110 		this(dlg, seconds.total!"seconds".to!uint, fireNow);
111 	}
112 
113 	/**
114 	 * Creates a new timeout cycle.
115 	 * Params:
116 	 *    	delegate() = 	the delegate to be executed
117 	 *      seconds = interval in seconds.
118 	 *      priority = Priority for the timeout function
119 	 *    	fireNow = 	When true the delegate will be executed emmidiatly
120 	 */
121 	this(bool delegate() dlg, uint seconds, GPriority priority, bool fireNow=false)
122 	{
123 		if ( fireNow && !dlg() )
124 			return;
125 
126 		timeoutListeners ~= dlg;
127 		timeoutID = g_timeout_add_seconds_full(priority, seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify);
128 	}
129 
130 	this(bool delegate() dlg, Duration seconds, GPriority priority, bool fireNow=false)
131 	{
132 		this(dlg, seconds.total!"seconds".to!uint, priority, fireNow);
133 	}
134 
135 	/** Removes the timeout from gtk */
136 	public void stop()
137 	{
138 		if ( timeoutID > 0 )
139 		{
140 			g_source_remove(timeoutID);
141 		}
142 	}
143 
144 	/**
145 	 * Removes the timeout from gtk
146 	 */
147 	~this()
148 	{
149 		stop();
150 	}
151 
152 	/**
153 	 * Adds a new delegate to this timeout cycle
154 	 * Params:
155 	 *    	dlg =
156 	 *    	fireNow =
157 	 */
158 	public void addListener(bool delegate() dlg, bool fireNow=false)
159 	{
160 		if ( fireNow && !dlg() )
161 			return;
162 
163 		timeoutListeners ~= dlg;
164 	}
165 
166 	/**
167 	 * The callback execution from glib
168 	 * Params:
169 	 *    	timeout =
170 	 * Returns:
171 	 */
172 	extern(C) static bool timeoutCallback(Timeout timeout)
173 	{
174 		bool runAgain = false;
175 		int i = 0;
176 
177 		while ( i<timeout.timeoutListeners.length )
178 		{
179 			if ( !timeout.timeoutListeners[i]() )
180 			{
181 				timeout.timeoutListeners = timeout.timeoutListeners[0..i] ~ timeout.timeoutListeners[i+1..$];
182 			}
183 			else
184 			{
185 				runAgain = true;
186 				++i;
187 			}
188 		}
189 
190 		return runAgain;
191 	}
192 
193 	/*
194 	 * Reset the timeout object when it's destroyed on the GTK side.
195 	 */
196 	extern(C) static void destroyTimeoutNotify(Timeout timeout)
197 	{
198 		timeout.timeoutListeners.length = 0;
199 		timeout.timeoutID = 0;
200 	}
201 
202 	/**
203 	 */
204 
205 	/**
206 	 * Sets a function to be called at regular intervals, with the default
207 	 * priority, %G_PRIORITY_DEFAULT.
208 	 *
209 	 * The given @function is called repeatedly until it returns %G_SOURCE_REMOVE
210 	 * or %FALSE, at which point the timeout is automatically destroyed and the
211 	 * function will not be called again. The first call to the function will be
212 	 * at the end of the first @interval.
213 	 *
214 	 * Note that timeout functions may be delayed, due to the processing of other
215 	 * event sources. Thus they should not be relied on for precise timing.
216 	 * After each call to the timeout function, the time of the next
217 	 * timeout is recalculated based on the current time and the given interval
218 	 * (it does not try to 'catch up' time lost in delays).
219 	 *
220 	 * See [memory management of sources][mainloop-memory-management] for details
221 	 * on how to handle the return value and memory management of @data.
222 	 *
223 	 * If you want to have a timer in the "seconds" range and do not care
224 	 * about the exact time of the first call of the timer, use the
225 	 * g_timeout_add_seconds() function; this function allows for more
226 	 * optimizations and more efficient system power usage.
227 	 *
228 	 * This internally creates a main loop source using g_timeout_source_new()
229 	 * and attaches it to the global #GMainContext using g_source_attach(), so
230 	 * the callback will be invoked in whichever thread is running that main
231 	 * context. You can do these steps manually if you need greater control or to
232 	 * use a custom main context.
233 	 *
234 	 * It is safe to call this function from any thread.
235 	 *
236 	 * The interval given is in terms of monotonic time, not wall clock
237 	 * time.  See g_get_monotonic_time().
238 	 *
239 	 * Params:
240 	 *     interval = the time between calls to the function, in milliseconds
241 	 *         (1/1000ths of a second)
242 	 *     function_ = function to call
243 	 *     data = data to pass to @function
244 	 *
245 	 * Returns: the ID (greater than 0) of the event source.
246 	 */
247 	public static uint add(uint interval, GSourceFunc function_, void* data)
248 	{
249 		return g_timeout_add(interval, function_, data);
250 	}
251 
252 	/**
253 	 * Sets a function to be called at regular intervals, with the given
254 	 * priority.  The function is called repeatedly until it returns
255 	 * %FALSE, at which point the timeout is automatically destroyed and
256 	 * the function will not be called again.  The @notify function is
257 	 * called when the timeout is destroyed.  The first call to the
258 	 * function will be at the end of the first @interval.
259 	 *
260 	 * Note that timeout functions may be delayed, due to the processing of other
261 	 * event sources. Thus they should not be relied on for precise timing.
262 	 * After each call to the timeout function, the time of the next
263 	 * timeout is recalculated based on the current time and the given interval
264 	 * (it does not try to 'catch up' time lost in delays).
265 	 *
266 	 * See [memory management of sources][mainloop-memory-management] for details
267 	 * on how to handle the return value and memory management of @data.
268 	 *
269 	 * This internally creates a main loop source using g_timeout_source_new()
270 	 * and attaches it to the global #GMainContext using g_source_attach(), so
271 	 * the callback will be invoked in whichever thread is running that main
272 	 * context. You can do these steps manually if you need greater control or to
273 	 * use a custom main context.
274 	 *
275 	 * The interval given is in terms of monotonic time, not wall clock time.
276 	 * See g_get_monotonic_time().
277 	 *
278 	 * Params:
279 	 *     priority = the priority of the timeout source. Typically this will be in
280 	 *         the range between %G_PRIORITY_DEFAULT and %G_PRIORITY_HIGH.
281 	 *     interval = the time between calls to the function, in milliseconds
282 	 *         (1/1000ths of a second)
283 	 *     function_ = function to call
284 	 *     data = data to pass to @function
285 	 *     notify = function to call when the timeout is removed, or %NULL
286 	 *
287 	 * Returns: the ID (greater than 0) of the event source.
288 	 */
289 	public static uint addFull(int priority, uint interval, GSourceFunc function_, void* data, GDestroyNotify notify)
290 	{
291 		return g_timeout_add_full(priority, interval, function_, data, notify);
292 	}
293 
294 	/**
295 	 * Sets a function to be called at regular intervals with the default
296 	 * priority, %G_PRIORITY_DEFAULT.
297 	 *
298 	 * The function is called repeatedly until it returns %G_SOURCE_REMOVE
299 	 * or %FALSE, at which point the timeout is automatically destroyed
300 	 * and the function will not be called again.
301 	 *
302 	 * This internally creates a main loop source using
303 	 * g_timeout_source_new_seconds() and attaches it to the main loop context
304 	 * using g_source_attach(). You can do these steps manually if you need
305 	 * greater control. Also see g_timeout_add_seconds_full().
306 	 *
307 	 * It is safe to call this function from any thread.
308 	 *
309 	 * Note that the first call of the timer may not be precise for timeouts
310 	 * of one second. If you need finer precision and have such a timeout,
311 	 * you may want to use g_timeout_add() instead.
312 	 *
313 	 * See [memory management of sources][mainloop-memory-management] for details
314 	 * on how to handle the return value and memory management of @data.
315 	 *
316 	 * The interval given is in terms of monotonic time, not wall clock
317 	 * time.  See g_get_monotonic_time().
318 	 *
319 	 * Params:
320 	 *     interval = the time between calls to the function, in seconds
321 	 *     function_ = function to call
322 	 *     data = data to pass to @function
323 	 *
324 	 * Returns: the ID (greater than 0) of the event source.
325 	 *
326 	 * Since: 2.14
327 	 */
328 	public static uint addSeconds(uint interval, GSourceFunc function_, void* data)
329 	{
330 		return g_timeout_add_seconds(interval, function_, data);
331 	}
332 
333 	/**
334 	 * Sets a function to be called at regular intervals, with @priority.
335 	 *
336 	 * The function is called repeatedly until it returns %G_SOURCE_REMOVE
337 	 * or %FALSE, at which point the timeout is automatically destroyed and
338 	 * the function will not be called again.
339 	 *
340 	 * Unlike g_timeout_add(), this function operates at whole second granularity.
341 	 * The initial starting point of the timer is determined by the implementation
342 	 * and the implementation is expected to group multiple timers together so that
343 	 * they fire all at the same time. To allow this grouping, the @interval to the
344 	 * first timer is rounded and can deviate up to one second from the specified
345 	 * interval. Subsequent timer iterations will generally run at the specified
346 	 * interval.
347 	 *
348 	 * Note that timeout functions may be delayed, due to the processing of other
349 	 * event sources. Thus they should not be relied on for precise timing.
350 	 * After each call to the timeout function, the time of the next
351 	 * timeout is recalculated based on the current time and the given @interval
352 	 *
353 	 * See [memory management of sources][mainloop-memory-management] for details
354 	 * on how to handle the return value and memory management of @data.
355 	 *
356 	 * If you want timing more precise than whole seconds, use g_timeout_add()
357 	 * instead.
358 	 *
359 	 * The grouping of timers to fire at the same time results in a more power
360 	 * and CPU efficient behavior so if your timer is in multiples of seconds
361 	 * and you don't require the first timer exactly one second from now, the
362 	 * use of g_timeout_add_seconds() is preferred over g_timeout_add().
363 	 *
364 	 * This internally creates a main loop source using
365 	 * g_timeout_source_new_seconds() and attaches it to the main loop context
366 	 * using g_source_attach(). You can do these steps manually if you need
367 	 * greater control.
368 	 *
369 	 * It is safe to call this function from any thread.
370 	 *
371 	 * The interval given is in terms of monotonic time, not wall clock
372 	 * time.  See g_get_monotonic_time().
373 	 *
374 	 * Params:
375 	 *     priority = the priority of the timeout source. Typically this will be in
376 	 *         the range between %G_PRIORITY_DEFAULT and %G_PRIORITY_HIGH.
377 	 *     interval = the time between calls to the function, in seconds
378 	 *     function_ = function to call
379 	 *     data = data to pass to @function
380 	 *     notify = function to call when the timeout is removed, or %NULL
381 	 *
382 	 * Returns: the ID (greater than 0) of the event source.
383 	 *
384 	 * Since: 2.14
385 	 */
386 	public static uint addSecondsFull(int priority, uint interval, GSourceFunc function_, void* data, GDestroyNotify notify)
387 	{
388 		return g_timeout_add_seconds_full(priority, interval, function_, data, notify);
389 	}
390 
391 	/**
392 	 * Creates a new timeout source.
393 	 *
394 	 * The source will not initially be associated with any #GMainContext
395 	 * and must be added to one with g_source_attach() before it will be
396 	 * executed.
397 	 *
398 	 * The interval given is in terms of monotonic time, not wall clock
399 	 * time.  See g_get_monotonic_time().
400 	 *
401 	 * Params:
402 	 *     interval = the timeout interval in milliseconds.
403 	 *
404 	 * Returns: the newly-created timeout source
405 	 */
406 	public static Source sourceNew(uint interval)
407 	{
408 		auto __p = g_timeout_source_new(interval);
409 
410 		if(__p is null)
411 		{
412 			return null;
413 		}
414 
415 		return new Source(cast(GSource*) __p, true);
416 	}
417 
418 	/**
419 	 * Creates a new timeout source.
420 	 *
421 	 * The source will not initially be associated with any #GMainContext
422 	 * and must be added to one with g_source_attach() before it will be
423 	 * executed.
424 	 *
425 	 * The scheduling granularity/accuracy of this timeout source will be
426 	 * in seconds.
427 	 *
428 	 * The interval given is in terms of monotonic time, not wall clock time.
429 	 * See g_get_monotonic_time().
430 	 *
431 	 * Params:
432 	 *     interval = the timeout interval in seconds
433 	 *
434 	 * Returns: the newly-created timeout source
435 	 *
436 	 * Since: 2.14
437 	 */
438 	public static Source sourceNewSeconds(uint interval)
439 	{
440 		auto __p = g_timeout_source_new_seconds(interval);
441 
442 		if(__p is null)
443 		{
444 			return null;
445 		}
446 
447 		return new Source(cast(GSource*) __p, true);
448 	}
449 }